package cn.mvcjava.dao;

import static org.hamcrest.CoreMatchers.nullValue;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import cn.mvcjava.utils.JdbcUtils;

//基本的类具体的dao 类要进行继承这个类。
public class BaseDao<T> {
	
//	反射类
	private Class<T> clazz;
	
	public BaseDao(){
//		使用构造方法初始化clazz; 这里的this值得是谁调用这里类，就是指的谁。
	 Type  supertype =	this.getClass().getGenericSuperclass();
	 if(supertype instanceof ParameterizedType) {
		 ParameterizedType pt =   (ParameterizedType) supertype;
		 Type[] tarry = pt.getActualTypeArguments();  // 返回一个类型，第一个元素就是我们要的 T ，user.class
		 if(tarry[0] instanceof Class) {
			 clazz = (Class<T>) tarry[0]; 
		 }
		  
	 }
		
	}
	
	QueryRunner queryRunner  =new QueryRunner();
	
//	对数据库有增删改查方法。
	
//	查询数据表得到返回值的第一条数据，封装成一个类的对象返回。不支持事物。
	public T get(String sql,Object...objects) {
		Connection connection = null;
		T  entity = null;
		try {
			connection= JdbcUtils.getConnection();
			entity = queryRunner.query(connection, sql,new BeanHandler<T>(clazz), objects);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JdbcUtils.closeConn(connection);
		} 
		return entity;
		
	}
	
//	带事物的数据库
//	null 里面传入要返回的类型对象。 这个时候必须使用到反射。
	
	public T get(Connection connection ,String sql,Object...objects) {
		 T  entity = null;
		try {
			connection= JdbcUtils.getConnection();
			entity = queryRunner.query(connection, sql,new BeanHandler<T>(clazz), objects);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JdbcUtils.closeConn(connection);
		} 
		return entity; 
	}
	
//	 获取所有的信息。
	public List<T> getList(String sql,Object...objects){
		
		Connection connection = null;
		List<T>    list =null;
		try {
			connection= JdbcUtils.getConnection();
			list = queryRunner.query(connection, sql,new BeanListHandler<T>(clazz), objects);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JdbcUtils.closeConn(connection);
		} 
		return list; 
	}
	
//	更新信息。  通用方法 insert update delete 通用方法。
	public int update(String sql,Object...objects) {
		Connection connection = null;
		int  rows = 0;
		try {
			connection= JdbcUtils.getConnection();
			rows = queryRunner.update(connection, sql, objects);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JdbcUtils.closeConn(connection);
		}  
	   return rows; 
	}
	
	
	public Object getValue(String sql,Object...objects) {
		Connection connection = null;
		Object  obj = null;
		try {
			connection= JdbcUtils.getConnection();
			obj = queryRunner.query(connection, sql,new ScalarHandler(), objects);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JdbcUtils.closeConn(connection);
		} 
		return obj;
		 
	}
	

}
